package cn.gailvlun.gll.widget

import android.content.Context
import android.media.MediaPlayer
import android.support.v7.widget.AppCompatSeekBar
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.SeekBar
import android.widget.TextView
import cn.gailvlun.gll.R
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import java.text.MessageFormat
import java.util.concurrent.TimeUnit


class CondensePlayView : LinearLayout {

    enum class PlayState {
        NOT_PLAYED, PLAYING, PAUSING, DONE
    }

    private var mState: PlayState? = PlayState.NOT_PLAYED

    private fun setState(state: PlayState) {
        this.mState = state
        when (state) {
            PlayState.PLAYING -> {
                
                iv?.setImageResource(R.drawable.icon_condense_pause)
                play()
            }
            PlayState.PAUSING -> {
                
                iv?.setImageResource(R.drawable.icon_play)
                pause()
            }
        }
    }

    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        View.inflate(context, R.layout.condense_play_view, this)

        setBackgroundResource(R.drawable.rounded_condense_play_bg)
        orientation = HORIZONTAL
        gravity = Gravity.CENTER_VERTICAL

        iv = findViewById(R.id.iv)
        acsb = findViewById(R.id.acsb)
        tvProgress = findViewById(R.id.tv_progress)

        iv?.setOnClickListener {
            when (mState) {
                PlayState.NOT_PLAYED -> {
                    iv?.setImageResource(R.drawable.icon_condense_pause)
                    setState(PlayState.PLAYING)
                }
                PlayState.PLAYING -> {
                    setState(PlayState.PAUSING)
                }
                PlayState.PAUSING -> {
                    setState(PlayState.PLAYING)
                }
            }
        }

        acsb?.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                if (fromUser) {
                    mMediaPlayer?.seekTo(progress)
                    setProgressText(progress)
                }
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {

            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {

            }

        })
    }

    private var iv: ImageView? = null
    private var acsb: AppCompatSeekBar? = null
    private var tvProgress: TextView? = null

    private var mMediaPlayer: MediaPlayer? = null

    private var mDuration: Int = 0

    fun setUrl(dataSource: String) {
        mMediaPlayer = MediaPlayer()
        mMediaPlayer?.setDataSource(dataSource)
        mMediaPlayer?.prepare()

        mDuration = mMediaPlayer?.duration!!
        acsb?.max = mDuration

        setProgressText(0)
    }

    private fun setProgressText(currentPosition: Int) {
        tvProgress?.text = "${getLongFromMill(currentPosition)}/${getLongFromMill(mDuration)}"
    }

    private fun getLongFromMill(mill: Int?): String {
        return if (mill != null) {
            format("{0, number, 00}:{1, number,00}", mill.div(1000 * 60), mill.div(1000) % 60)
        } else {
            "00:00"
        }
    }

    private fun format(pattern: String, vararg arguments: Any): String {
        return MessageFormat.format(pattern, *arguments)
    }

    fun play() {
        mMediaPlayer?.start()
        mMediaPlayer?.setOnCompletionListener {
            setState(PlayState.PAUSING)
        }

        Observable.interval(0, 100, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Observer<Long> {
                    override fun onNext(t: Long) {
                        val currentPosition = mMediaPlayer?.currentPosition!!
                        if (currentPosition > mDuration) {
                            acsb?.progress = 0
                            mMediaPlayer?.seekTo(0)
                        } else if (currentPosition <= mDuration) {
                            acsb?.progress = currentPosition
                            setProgressText(mMediaPlayer?.currentPosition!!)
                        }
                    }

                    override fun onError(e: Throwable) {

                    }

                    override fun onComplete() {

                    }

                    override fun onSubscribe(d: Disposable) {
                        disposable = d
                    }
                })
    }

    private var disposable: Disposable? = null

    fun pause() {
        disposable?.dispose()
        mMediaPlayer?.pause()
    }

    fun onDestroy() {
        disposable?.dispose()
        mMediaPlayer?.stop()
        mMediaPlayer?.release()
    }
}